<?php
namespace app\admin\controller;
use app\admin\controller\Common;
use app\service\orderService;
use think\Db;
use think\Controller;
use app\service\Aop;
use app\service\apiinvoiceService;
use app\service\billService;
use think\Log;
use invoice\Api;
ini_set('max_execution_time','300');
class Aliinvoice2 extends Controller{
	
	public function test(){
        /*$path=dir(getcwd())->path.'/invoice/'.date('Ymd');
        if (! file_exists ( $path )) {
            mkdir ( "$path", 0777, true );
        }
        $address = $path."/092742712.txt";
        file_put_contents($address,file_get_contents("php://input"),FILE_APPEND);//将数据读入文本*/
        $str2='{"payerTelPhone":"","orderNo":"2020090711192727322875","sign":"E4kfz1ei%2FQ%2B%2B4nzGJnr5E23ATKv7Q8gKcWtb%2F6kqXxDhCMt3m3QTTTZ7PJ5wMPMlKLWRZynB7%2B1EmbZ5ljMyRaS9o4DdgADz6n8jTktOSvJwe%2Bf0qtVlfc87Qr7IGXMA08zxCXbbPwkw8pkO86EF1aejEKDLNHLg5rC72taedX0cmfcT6oy2SN7AQdmxP5Jt1KdgdpUQchVxI%2FBBGjPQ0bMzlqYXdk56EFLkvauGQ90VY0D0PYIkVU9j%2Bv1LMwVStk5ZgTOBUFHeybM1u1opq2LZT7hM9qx9wCagBKLliC4ds3piJZDtr3T5M21wDzILBISTk4t6oOrlacK90IKeNw%3D%3D","mShortName":"zdwu","payerBankName":"","invoiceAmount":"0.01","payerBankAccount":"","userId":"2088112618452297","userMobileNo":"18856151031","applyId":"2020091100152005290001733804","tradeTime":"","payerAddress":"","subShortName":"zdwu","payerName":"杨战磊","payerRegisterNo":"","userEmail":"2052359884@qq.com","isRetryOpen":false}';
        $str = json_decode($str2,JSON_UNESCAPED_UNICODE);
        $res=$this->verifysign($str);
		
        if($res){
            $info = $this->object_to_array($str);
            
            $res=$this->invoiceSend($info);
            var_dump($res);
            
            //$this->yzl_fsockopen('http://www.wuye.zfbzhsq.com/admin/aliinvoice/invoiceSend',$info);
            
        } 	
	}
	

    public function invoiceSend($info){

       
        
        $invoice=Db::table("billparkorder")->where("out_trade_no",$info["orderNo"])->find();
        
        if(empty($invoice)){
            return "1";
        }
        $num_back=$invoice['num_back']+1;
         Db::table("billparkorder")
                ->where('id',$invoice["id"])
                ->update([
                    "num_back"=>$num_back
                ]);
        $invoiceinfo=$this->invoiceApply($invoice["id"]);
        if($invoiceinfo["errorCode"]=="0"){
            
           
            $propertyinfo=Db::table("property")->where("id",$invoice["property_id"])->field("service_id")->find();
            $serviceinfo=Db::table("service")->where("id",$propertyinfo["service_id"])->find();
            //var_dump($info);
            $data["m_short_name"]=$info["mShortName"];
            $data["sub_m_short_name"]=$info["subShortName"];
            $data["apply_id"]=$info["applyId"];
            
            
            $data["invoice_date"]=$invoiceinfo["invoice_date"];
            $data["sum_amount"]=$info["invoiceAmount"];
            $data["tax_amount"]=round(($info["invoiceAmount"]*$serviceinfo["taxrate"])/(1+$serviceinfo["taxrate"]),2);//合计税额，票面上的合计税额
            $data["ex_tax_amount"]=$data["sum_amount"]-$data["tax_amount"];//不含税金额
            $data["item_name"]="餐饮费";
            $data["item_no"]="1010101990000000000";
            $data["item_spec"]="G39";
            $data["item_unit"]="台";
            $data["item_quantity"]="1";
            $data["item_unit_price"]=$data["ex_tax_amount"];
            $data["item_ex_tax_amount"]=$data["ex_tax_amount"];
            $data["item_tax_amount"]=$data["tax_amount"];
            $data["item_sum_amount"]=$data["sum_amount"];
            $data["item_tax_rate"]=$serviceinfo["taxrate"];
            
            $data["out_trade_no"]=$info["orderNo"];
            $data["invoice_type"]='BLUE';
            $data["invoice_kind"]='PLAIN';

            $data["invoice_code"]=$invoiceinfo["invoiceCode"];//发票代码，该字段与invoice_no构成一张发票的唯一标识
            $data["invoice_no"]=$invoiceinfo["invoiceNum"];//发票号码，该字段与invoice_code构成一张发票的唯一标识。
            //购买方信息
            $data["title_name"]=$info["payerName"];
            $data["payer_register_no"]=$info["payerRegisterNo"];//购方税号
            $data["payer_address_tel"]=$info["payerAddress"].$info["userMobileNo"];
            $data["payer_bank_name_account"]=$info["payerBankName"];
            
            //销售方信息 根据停车场查询
            $data["payee_register_no"]=$serviceinfo["fp_saler_tax_num"];
            $data["payee_register_name"]=$serviceinfo["name"];
            $data["payee_address_tel"]=$serviceinfo["fp_saler_account"];
            
            $data["payee_bank_name_account"]=$serviceinfo["bank"];
            $data["check_code"]='';
            $data["out_invoice_id"]=$info["orderNo"];
            $data["ori_blue_inv_code"]='';
            $data["ori_blue_inv_no"]='';
            $data["file_download_type"]='PDF';
            $data["file_download_url"]=$invoiceinfo["invoiceFileUrl"];
            $data["payee"]='';
            $data["checker"]='';
            $data["clerk"]='';
            $data["invoice_memo"]="停车费";
            $data["xtend_fields"]='';
           
            $api=new apiinvoiceService();
            $res=$api->invoiceSend(json_encode($data));
            if(($res->code!="10000")&&($num_back<3)){
                $this->yzl_fsockopen('http://www.wuye.zfbzhsq.com/admin/aliinvoice/invoiceSend',$info);
            }
            Log::write($res,"yang");
        }   
    }

    public function invoiceApply($id){
        $invoiceinfo=Db::table('billparkorder')->find($id);
        if($invoiceinfo["invoice_type"]!="3"){
            $res=$this->CheckEInvoice($id);
            return $res;
        }
        if(!empty($invoiceinfo["invoiceFileUrl"])){
            return $invoiceinfo;
        }
		
		
		//根据商家id查询开票信息
		$propertyinfo=Db::table('property')->where('id',$invoiceinfo["property_id"])->find();
		$serviceinfo=Db::table('service')->where('id',$propertyinfo["service_id"])->find();
		
        
        
        //购方手机（开票成功会短信提醒购方，不受推送方式影响）(Y)
        $buyerPhone=$invoiceinfo["buyerPhone"];

        $buyerName=$invoiceinfo["buyerName"];
        $buyerTaxNum=$invoiceinfo["buyerTaxnum"];
        $buyerTel=$invoiceinfo["buyerTel"];
        $buyerAddress=$invoiceinfo["buyerAddress"];
        $buyerAccount=$invoiceinfo["buyerAccount"];

        //订单号
        $orderNo =$invoiceinfo["out_trade_no"];
        //订单时间
        $invoiceDate = date('Y-m-d H:i:s',time());
        $clerk="";
            //订单详情
            //金额
            $money=$invoiceinfo["pay_money"];
            //税率
            $taxrate="0.06";
            //税额
            $tax=$taxrate*$money;

        $invoiceDetail= "{'goodsName':'车位费','num':'1','price':'{$money}','withTaxFlag':'1','taxRate':'{$taxrate}','tax':'{$tax}'}";
        
        $timestmp = time();
        $remark="支付宝支付";
        //判断access_token是否到期
        $second = strtotime(date('Y-m-d H:i:s',time()))-strtotime($serviceinfo['fp_expires_in']);
        if($second <86400){
            //未过期
            $access_token = $serviceinfo['fp_access_token'];
        }else{
            //过期从新获取
            $access_token = $this->accessToken($serviceinfo['fp_app_key'],$serviceinfo['fp_app_secret']);
        }
        
        $appKey = $serviceinfo["fp_app_key"];
     	$appSecret = $serviceinfo["fp_app_secret"];
    	$token = $access_token;// please store the token and refresh it before expired
    	$taxnum = $serviceinfo["fp_saler_tax_num"];
        
    	$url = "https://sdk.nuonuo.com/open/v1/services"; // change to online domain
    	$method = "nuonuo.electronInvoice.requestBilling"; // change to your method
		$senid = uniqid(); // generate your meaningful senid
		
		$invoiceDate = date('Y-m-d H:i:s',time());
        $orderNo = time().rand(100000,999999);
        $timestmp = time(); 
        $buyerName=$invoiceinfo["buyerName"];
        $buyerPhone=$invoiceinfo["buyerPhone"];
        //$buyerPhone="188561510";
        $fp_saler_tax_num=$serviceinfo['fp_saler_tax_num'];
        $salerAddress=$serviceinfo['address'];
        $salerTel=$serviceinfo['phone'];
        $salerAddress=$serviceinfo['address'];
        $salerAccount=$serviceinfo['fp_saler_account'];
        $emt="";
        
        //var_dump($content);
        $body = "{
        \"order\": {
            \"buyerName\": \"$buyerName\",
            \"orderNo\": \"$orderNo\",
            \"invoiceDate\": \"$invoiceDate\",
            \"clerk\": \"\",
            \"salerTaxNum\": \"$fp_saler_tax_num\",
            \"salerTel\": \"$salerTel\",
            \"salerAddress\": \"$salerAddress\",
            \"salerAccount\": \"$salerAccount\",
            \"invoiceType\": \"1\",
            \"pushMode\": \"1\",
            \"buyerPhone\": \"$buyerPhone\",
            \"remark\": \"$remark\",
            \"invoiceDetail\": [$invoiceDetail],
            \"callBackUrl\": \"http://www.jfzhiwen.com/admin/invoice/callback/\"
            }
        }";
        $result = Api::sendPostSyncRequest($url, $senid, $appKey, $appSecret, $token, $taxnum, $method, $body);
        //var_dump($result);
		$result = json_decode($result, true);
		Log::write($result,"invoiceresult");
        if($result['code'] == 'E0000'){
            $invoiceSerialNum = $result['result']['invoiceSerialNum'];
            $invoice["invoice_serial_num"] = $result['result']['invoiceSerialNum'];
            $invoice["invoice_time"]=date('Y-m-d H:i:s');
            $invoice["invoice_type"]="1";
            //$invoice["status"]="2";
            $invoice["invoice_date"]=date('Y-m-d');
            $res=Db::table('billparkorder')->where('id', $id)->update($invoice);
            $res=$this->CheckEInvoice($id);

            return $res;
        }else{
            $res["errorCode"]="1";
            $res["error"]= $result['describe'];
            return $res;
        }
    }

    //查询发票
    public function CheckEInvoice($id){
        sleep(30);
        //查询发票序列号
        $data=Db::table('billparkorder')->find($id);
        if(!empty($data["invoiceFileUrl"])){
            $data["errorCode"]="0";
            return $data;
            
        }
       	//根据商家id查询开票信息
		$propertyinfo=Db::table('property')->where('id',$data["property_id"])->find();
		$serviceinfo=Db::table('service')->where('id',$propertyinfo["service_id"])->find();
        
       //判断access_token是否到期
        $second = strtotime(date('Y-m-d H:i:s',time()))-strtotime($serviceinfo['fp_expires_in']);
        if($second <86400){
            //未过期
            $access_token = $serviceinfo['fp_access_token'];
        }else{
            //过期从新获取
            $access_token = $this->accessToken($serviceinfo['fp_app_key'],$serviceinfo['fp_app_secret']);
        }
         //var_dump($access_token);die;
        $timestmp = time();
       
		$appKey = $serviceinfo["fp_app_key"];
     	$appSecret = $serviceinfo["fp_app_secret"];
    	$token = $access_token;// please store the token and refresh it before expired
    	$taxnum = $serviceinfo["fp_saler_tax_num"];
    
    	$url = "https://sdk.nuonuo.com/open/v1/services"; // change to online domain
    	$method = "nuonuo.electronInvoice.CheckEInvoice"; // change to your method
		$senid = uniqid(); // generate your meaningful senid
		$body = json_encode(
			array(
				"invoiceSerialNum" => array($data['invoice_serial_num'])
			)
		);
        
		$result = Api::sendPostSyncRequest($url, $senid, $appKey, $appSecret, $token, $taxnum, $method, $body);

        // dump($result,true);exit();
        $result = json_decode($result, true);
        Log::write($result,"yangPDF");
        if($result['code'] == 'E0000'){
            //return $result['result'][0]['invoiceFileUrl'];
            Db::table("billparkorder")
                ->where('id',$id)
                ->update([
                    "invoiceFileUrl"=>$result['result'][0]['invoiceFileUrl'],
                    "invoiceNum"=>$result['result'][0]["invoiceNum"],
                    "invoiceCode"=>$result['result'][0]['invoiceCode']
                ]);

            $res=Db::table("billparkorder")->where('id',$id)->find();
            $res["errorCode"]="0";
            return $res;
        }else{
            $res["errorCode"]="1";
            $res["error"]= $result['describe'];
            return $res;
            return json(['error' => $result['describe']]);
        }
    }
    public function invoice(){
        $path=dir(getcwd())->path.'/invoice/'.date('Ymd');
        if (! file_exists ( $path )) {
            mkdir ( "$path", 0777, true );
        }
        $address = $path."/".date('His').rand(100,999).'.txt';
        file_put_contents($address,file_get_contents("php://input"),FILE_APPEND);//将数据读入文本
        
        $str = json_decode(file_get_contents($address),JSON_UNESCAPED_UNICODE);
        $res=$this->verifysign($str);
		
        if($res){
            $info = $this->object_to_array($str);
            $aop = new Aop();
       
            $params["resultCode"]="APPLY_SUCCESS";
            $params["resultMsg"]= "申请成功";
            $params["resultUrl"]="";
            $str=$this->MakeSign($params);
            
            $str=iconv("UTF-8","gbk",$str);
            
            $rest_sign= $aop-> rsaSign1($str) ;
            $rest_sign = urlencode($rest_sign);
            $params["sign"]=$rest_sign;
            $testJSON=json_encode ($params,JSON_UNESCAPED_UNICODE) ;
            //Log::write($testJSON,"testJSON");
            
            echo $testJSON;
            

            //更新发票的信息
            $invoice["buyerPhone"]=$info["userMobileNo"];
            if(empty($info["userMobileNo"])){
                $invoice["buyerPhone"]="";
            }
            $invoice["buyerName"]=$info["payerName"];
            $invoice["buyerTaxnum"]=$info["payerRegisterNo"];//购方税号
            $invoice["buyerTel"]=$info["payerTelPhone"];
            $invoice["buyerAddress"]=$info["payerAddress"];
            $invoice["buyerAccount"]=$info["payerBankName"];
            $invoice["applyId"]=$info["applyId"];
            Db::table("billparkorder")->where("out_trade_no",$info["orderNo"])->update($invoice);

            
            $this->yzl_fsockopen('http://www.wuye.zfbzhsq.com/admin/aliinvoice/invoiceSend',$info);
            
        } 	
	}

    public function yzl_fsockopen($url,$post_data=array(),$cookie=array()){
        $url_arr = parse_url($url);
        $port = isset($url_arr['port'])?$url_arr['port']:80;
        if($url_arr['scheme'] == 'https'){
            $url_arr['host'] = 'ssl://'.$url_arr['host'];
        }
        $fp = fsockopen($url_arr['host'],$port,$errno,$errstr,30);
        if(!$fp) return false;
        $getPath = isset($url_arr['path'])?$url_arr['path']:'/index.php';
        $getPath .= isset($url_arr['query'])?'?'.$url_arr['query']:'';
        $method = 'GET';  //默认get方式
        if(!empty($post_data)) $method = 'POST';
        $header = "$method  $getPath  HTTP/1.1\r\n";
        $header .= "Host: ".$url_arr['host']."\r\n";
        if(!empty($cookie)){  //传递cookie信息
            $_cookie = strval(NULL);
            foreach($cookie AS $k=>$v){
                $_cookie .= $k."=".$v.";";
            }
            $cookie_str = "Cookie:".base64_encode($_cookie)."\r\n";
            $header .= $cookie_str;
        }
        if(!empty($post_data)){  //传递post数据
            $_post = array();
            foreach($post_data AS $_k=>$_v){
                $_post[] = $_k."=".urlencode($_v);
            }
            $_post = implode('&', $_post);
            $post_str = "Content-Type:application/x-www-form-urlencoded; charset=UTF-8\r\n";
            $post_str .= "Content-Length: ".strlen($_post)."\r\n";  //数据长度
            $post_str .= "Connection:Close\r\n\r\n";
            $post_str .= $_post;  //传递post数据
            $header .= $post_str;
        }else{
            $header .= "Connection:Close\r\n\r\n";
        }
        fwrite($fp, $header);
        //echo fread($fp,1024);
        usleep(1000); // 这一句也是关键，如果没有这延时，可能在nginx服务器上就无法执行成功
        fclose($fp);
        return true;
    }



	//当access_token超时时，获取access_token
    public function accessToken($client_id,$client_secret){
        $res = Api::getMerchantToken($client_id, $client_secret);
		$tmpInfo = json_decode($res);

        
        if(property_exists($tmpInfo,'error')){
            //var_dump($tmpInfo);die;
            //return $tmpInfo;
            $this->error($tmpInfo->error.',access_token获取失败');
        }
        $data['fp_access_token'] = $tmpInfo->access_token;//获取access_token
        $data['fp_expires_in'] = date('Y-m-d H:i:s',time());
        $data['id'] = (new billService())->serviceFpAppKey($client_id);
        // 存储access_token
        $result = (new billService())->serviceUpdate($data);
        return $data['fp_access_token'];
        // $tmpInfo = '{"access_token":"10ffd45208fb4464aa6fee00vthjozss","expires_in":86400}';
        
    }

    
    
	
	public function ToUrlParam($value){
        $buff = "";
        foreach($value as $k => $v){
            if($k != "sign" &&  !is_array($v)){
                $buff .= $k . "=" . $v . "&";
            }
        }
        $buff = trim($buff, "&");
        return $buff;
    }

    //生成签名
    protected function MakeSign($arr){
        //签名步骤一：按字典序排序参数
        ksort($arr);
        
        $string = $this->ToUrlParam($arr);
       return $string;
        //签名步骤二：在string后加入KEY
               //签名步骤三：MD5加密
        //$string = md5($string);

        //签名步骤四：所有字符转为大写
        //$result = strtoupper($string);
        return $result;
    }   
    
	protected function verifysign($str){
        $info = $this->object_to_array($str);
        $sign=$info["sign"];
        unset($info["sign"]);
        $str=$this->MakeSign($info);
        $str=iconv("UTF-8","gbk",$str);
        $aop=new Aop();  
        $res=$aop->verify($str, urldecode($sign),  $signType = 'RSA');
        return $res;
    }
	
	//将对象转换成数组
    public function object_to_array($obj){
        $_arr = is_object($obj) ? get_object_vars($obj) :$obj;
        foreach($_arr as $key=>$val){
            if($key !== 'gioouts'){
                if($key !=='isRetryOpen'){
                    $val = (is_array($val) || is_object($val)) ? $this->object_to_array($val):$val;
                    $arr[$key] = $val;
                }else{
                    if($val){
                        $arr[$key] = "true";
                    }else{
                        $arr[$key] = "false";
                    }
                }
                
            }
        }
        return $arr;
    }
}